package cn.com.libertymutual.production.service.impl.business;

import cn.com.libertymutual.production.model.nomorcldatasource.*;
import cn.com.libertymutual.production.pojo.request.*;
import cn.com.libertymutual.production.pojo.response.ItemKind;
import cn.com.libertymutual.production.pojo.response.Response;
import cn.com.libertymutual.production.service.api.business.PlanBusinessService;
import cn.com.libertymutual.production.utils.Constant.BUSINESSLOGTYPE;
import cn.com.libertymutual.production.utils.Constant.BUSINESSTYPE;
import cn.com.libertymutual.production.utils.Constant.OPERTYPE;
import cn.com.libertymutual.production.utils.ObjectUtil;
import com.github.pagehelper.PageInfo;
import com.xiaoleilu.hutool.util.CollectionUtil;
import com.xiaoleilu.hutool.util.StrUtil;

import io.swagger.models.auth.In;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 事务管理注意事项：
 * 1. 新增/修改操作必须启用事务
 * 2. 方法体内部抛出异常即可启用事务
 * @author Steven.Li
 * @date 2017年7月28日
 * 
 */
@Service
@Transactional(rollbackFor = Exception.class, transactionManager = "transactionManagerCoreData")
public class PlanBusinessServiceImpl extends PlanBusinessService {
	
	@Override
	public Response findPrpdRiskPlan(PrpdRiskPlanRequest prpdRiskPlanRequest) {
		Response result = new Response();
		try {
			PageInfo<PrpdriskplanWithBLOBs> pageInfo = prpdRiskPlanService
					.findPrpdRiskPlan(prpdRiskPlanRequest);
			result.setTotal(pageInfo.getTotal());
			result.setResult(pageInfo.getList());
			result.setSuccess();
		} catch (Exception e) {
			log.error("系统异常错误！", e);
			result.setAppFail();
			result.setResult(e.getMessage());
		}
		return result;
	}

	@Override
	public Response findPrpdItemLibrary(RiskKindRequest request) {
		Response result = new Response();
		List<ItemKind> items = new ArrayList<>();
		try {
			for (Prpdkind kind : request.getKinds()) {
				List<ItemKind> currentItems = prpdItemLibraryService
						.findItemByRiskKind(request.getRisk().getRiskcode(),
								request.getRisk().getRiskversion(),
								kind.getKindcode(), kind.getKindversion());
				items.addAll(currentItems);
			}
			result.setResult(items);
			result.setSuccess();
		} catch (Exception e) {
			log.error("系统异常错误！", e);
			result.setAppFail();
			result.setResult(e.getMessage());
		}
		return result;
	}

	@Override
	public Response getNewPlanSerialno(String riskCode) throws Exception {

		Response result = new Response();

		String newSerialNo = "";
		String classCode = riskCode.substring(0, 2);
		List<Prpdserialno> list = prpdSerialNoService.findPrpdSerialno(
				BUSINESSTYPE.plan.toString(), classCode, riskCode);
		try {
			if (list.isEmpty()) {
				newSerialNo = "00001";
				prpdSerialNoService.insertPrpdSerialno(
						BUSINESSTYPE.plan.toString(), classCode, riskCode, 1);
			} else {
				Integer dbSerialNo = list.get(0).getSerialno();
				newSerialNo = StrUtil.padPre(dbSerialNo.toString(), 5, '0');
			}
			result.setResult("PLAN" + riskCode + newSerialNo);
		} catch (Exception e) {
			log.error("系统异常错误！", e);
			throw e;
		}
		return result;
	}

	@Override
	public Response findKindsByRisk(String riskCode, String riskVersion) {
		Response result = new Response();
		try {
			List<Prpdkindlibrary> list = prpdKindService.findKindsByRisk(
					riskCode, riskVersion);
			result.setResult(list);
			result.setSuccess();
		} catch (Exception e) {
			log.error("系统异常错误！", e);
			result.setAppFail();
			result.setResult(e.getMessage());
		}
		return result;
	}

	@Override
	public Response insertPlanInfo(PlanAddRequest request) throws Exception {

		Response result = new Response();

		try {
			// 保存方案数据到prpdriskplan
			PrpdriskplanWithBLOBs riskPlan = new PrpdriskplanWithBLOBs();
			riskPlan.setPlancode(request.getPlancode());
			riskPlan.setRiskcode(request.getRisk().getRiskcode());
			riskPlan.setRiskversion(request.getRisk().getRiskversion());
			riskPlan.setPlancname(request.getPlancname());
			riskPlan.setPlanename(request.getPlanename());
			riskPlan.setSerialno(1L);
			riskPlan.setValidstatus(request.getValidstatus());
			riskPlan.setFlag(request.getPlantype());
			riskPlan.setPlantype(request.getPlantype());
			if(!StringUtils.isEmpty(request.getApplycomcode()) && request.getApplycomcode().contains("ALL")) {
				riskPlan.setApplycomcode("ALL");
			} else {
				riskPlan.setApplycomcode(request.getApplycomcode());
			}
			riskPlan.setApplychannel(request.getApplychannel());
			riskPlan.setAutoundwrt(request.getAutoundwrt());
			riskPlan.setAutodoc(request.getAutodoc());
			riskPlan.setPeriodtype(request.getPeriodtype());
			riskPlan.setPeriod(Integer.valueOf("".equals(request.getPeriod()) ? "0"
					: request.getPeriod()));
			riskPlan.setOccupationcode(request.getOccupationcode());
			riskPlan.setTraveldestination(request.getTraveldestination());
			prpdRiskPlanService.insert(riskPlan);

			//保存方案数据到prpdration
			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			//JIRA:PRO-171  核心根据序号  （serialno） 来排序并加载条款信息，如果附加险的序号排在主险前可能会引起一些问题，希望平台可以控制下，配置方案时先选主险后选附加险
			List<Prpdkindlibrary> sortedKinds = new ArrayList<Prpdkindlibrary>();
			for (Prpdkindlibrary kind : request.getKinds()) {
				if (kind.getKindcode().contains("M")) {
					sortedKinds.add(kind);
				}
			}
			for (Prpdkindlibrary kind : request.getKinds()) {
				if (kind.getKindcode().contains("S")) {
					sortedKinds.add(kind);
				}
			}
			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

			StringBuffer planDetails = new StringBuffer();
			Prpdration ration = new Prpdration();
			long serialNo = 1;
			for (Prpdkindlibrary kind : sortedKinds) {
				ration.setRationtype(request.getPlantype());
				ration.setRiskcode(request.getRisk().getRiskcode());
				ration.setRiskversion(request.getRisk().getRiskversion());
				ration.setPlancode(request.getPlancode());
				ration.setPlancname(request.getPlancname());
				ration.setPlanename(request.getPlanename());
				ration.setSerialno(serialNo);
				ration.setKindcode(kind.getKindcode());
				ration.setKindversion(kind.getKindversion());
				ration.setKindcname(kind.getKindcname());
				ration.setKindename(kind.getKindename());
				ration.setStartdate(kind.getStartdate());
				ration.setEnddate(kind.getEnddate());
				ration.setClausecode(kind.getClausecode());

				Prpdkind criteria = new Prpdkind();
				criteria.setRiskcode(request.getRisk().getRiskcode());
				criteria.setRiskversion(request.getRisk().getRiskversion());
				criteria.setKindcode(kind.getKindcode());
				criteria.setKindversion(kind.getKindversion());
				List<Prpdkind> ownerRiskKind = prpdKindService.select(criteria);
				ration.setOwnerriskcode(ownerRiskKind.get(0).getOwnerriskcode());

				ration.setCalculateflag(kind.getCalculateflag());
				ration.setWaysofcalc(kind.getWaysofcalc());
				ration.setValidstatus("1");
				ration.setDelflag(request.getDelflag());
				for (AmountPremium amountPremium : request.getKinditems()) {
					if (kind.getKindcode().equals(amountPremium.getKindcode())) {
						ration.setSerialno(serialNo++);
						ration.setItemcode(amountPremium.getItemcode());
						ration.setItemcname(amountPremium.getItemcname());
						ration.setItemename(amountPremium.getItemename());
						ration.setItemflag(amountPremium.getItemflag());
						ration.setFreeitem3(amountPremium.getOwnerFlag());
						ration.setQuantity(Long.valueOf(amountPremium
								.getQuantity()));
						ration.setCurrency(amountPremium.getCurrency());
						ration.setAmount(new BigDecimal(amountPremium
								.getAmount()));
						ration.setUnitamount(new BigDecimal(amountPremium
								.getUnitamount()));
						ration.setRate(new BigDecimal(amountPremium.getRate()));
						ration.setDiscount(new BigDecimal(amountPremium
								.getDiscount()));
						ration.setPremium(new BigDecimal(amountPremium
								.getPremium()));
						ration.setUnitpremium(new BigDecimal(amountPremium
								.getUnitpremium()));
						ration.setCalculateflag(amountPremium.getCalculateflag());
						String prpdRationFlag = env.getProperty("prpdration."+ request.getRisk().getRiskcode() +".flag");
						if(StringUtils.isEmpty(prpdRationFlag)) {
							ration.setFlag("00");
						} else {
							ration.setFlag(prpdRationFlag.trim());
						}
						prpdrationService.insert(ration);
						planDetails.append("新增方案明细数据:"
								+ ObjectUtil.info(ration) + ";");
					}
				}
			}

			//////////////////////////////////////////////////////////////////////////////
			//针对复制的方案的情况，如果已配置因子，则复制并保存因子配置
			if (request.getOriginalPlan() != null) {
				Prpdriskplan planCriteria = new Prpdriskplan();
				planCriteria.setPlancode(request.getOriginalPlan().getPlancode());
				planCriteria.setRiskcode(request.getOriginalPlan().getRiskcode());
				planCriteria.setRiskversion(request.getOriginalPlan().getRiskversion());
				List<Prpdplanprops> planProps = prpdPlanPropsService.select(planCriteria);
				if (!planProps.isEmpty()) {
					////////////////////////////////////////////////////////////////////////////////////////
					/////////////////2724-座位类型特殊处理，临时添加，后期将移除/////////////////////////////////
					////////////////////////////////////////////////////////////////////////////////////////
					if ("2724".equals(request.getOriginalPlan().getRiskcode())) {
						List<Prpdplanprops> multiProps = new ArrayList<Prpdplanprops>();
						for (Prpdplanprops prop : planProps) {
							if ("00001".equals(prop.getPropscode())) { // 00001 - 座位
								multiProps.add(prop);
							}
						}
						if (!CollectionUtil.isEmpty(multiProps)) {
							Prpdplanprops regionProp = null;
							Prpdration record = new Prpdration();
							for (Prpdplanprops prop : multiProps) {
								regionProp = prop;
								record.setFreeitem1(prop.getPropsvalue());
								record.setFreeitem2("");
								if ("1".equals(prop.getPropstype())) { // 座位区间值，优先保存
									record.setFreeitem1(regionProp
											.getStartvalue());
									record.setFreeitem2(regionProp
											.getEndvalue());
									break;
								}
							}
							Prpdration criteria = new Prpdration();
							criteria.setPlancode(request.getPlancode());
							criteria.setRiskcode(request.getRisk().getRiskcode());
							criteria.setRiskversion(request.getRisk().getRiskversion());
							prpdrationService.updateByCriteria(record, criteria);
						}
					}
					////////////////////////////////////////////////////////////////////////////////////////

					Map<String, Integer> lineNos = new HashMap<String, Integer>();
					for (Prpdplanprops prop : planProps) {
						prop.setPlancode(request.getPlancode());
						Integer lineNo = lineNos.get(prop.getPropscode());
						if (lineNo == null) {
							lineNo = 1;
						} else {
							lineNo++;
						}
						lineNos.put(prop.getPropscode(), lineNo);
						prop.setLineno(lineNo.toString());
						if ("0".equals(prop.getPropstype())) {
							prop.setStartvalue(null);
							prop.setEndvalue(null);
						} else {
							prop.setPropsvalue(null);
						}
						prop.setValidstatus("1");
						prpdPlanPropsService.insert(prop);
					}
				}
			}
			//////////////////////////////////////////////////////////////////////////////

			int nextPlanSerialNo = Integer.valueOf(request.getPlancode()
					.substring(8)) + 1;
			prpdSerialNoService.updatePrpdSerialno(
					BUSINESSTYPE.plan.toString(), request.getRisk()
							.getRiskcode().substring(0, 2), request.getRisk()
							.getRiskcode(), nextPlanSerialNo);

			// ********************************************************************************
			// 方案日志
			systemLog
					.save(BUSINESSLOGTYPE.PLAN, OPERTYPE.INSERT,
							request.getPlancode(),
							"新增方案基础数据:" + ObjectUtil.info(riskPlan) + ";"
									+ planDetails);
			// ********************************************************************************
		} catch (Exception e) {
			log.error("系统异常错误！", e);
			throw e;
		}

		return result;
	}
	@Override
	public Response insertPlanInfo2(PlanAddRequest2 request) throws Exception {

		Response result = new Response();

		try {
			// 保存方案数据到prpdriskplan
			PrpdriskplanWithBLOBs riskPlan = new PrpdriskplanWithBLOBs();
			riskPlan.setPlancode(request.getPlancode());
			riskPlan.setRiskcode(request.getRisk().getRiskcode());
			riskPlan.setRiskversion(request.getRisk().getRiskversion());
			riskPlan.setPlancname(request.getPlancname());
			riskPlan.setPlanename(request.getPlanename());
			riskPlan.setSerialno(1L);
			riskPlan.setValidstatus(request.getValidstatus());
			riskPlan.setFlag(request.getPlantype());
			riskPlan.setPlantype(request.getPlantype());
			if(!StringUtils.isEmpty(request.getApplycomcode()) && request.getApplycomcode().contains("ALL")) {
				riskPlan.setApplycomcode("ALL");
			} else {
				riskPlan.setApplycomcode(request.getApplycomcode());
			}
			riskPlan.setApplychannel(request.getApplychannel());
			riskPlan.setAutoundwrt(request.getAutoundwrt());
			riskPlan.setAutodoc(request.getAutodoc());
			riskPlan.setPeriodtype(request.getPeriodtype());
			riskPlan.setPeriod(Integer.valueOf("".equals(request.getPeriod()) ? "0"
					: request.getPeriod()));
			riskPlan.setOccupationcode(request.getOccupationcode());
			riskPlan.setTraveldestination(request.getTraveldestination());
			prpdRiskPlanService.insert(riskPlan);

			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //保存因子组数据到prpdplansub
            List<List<Prpdplansub>> propsGroup = request.getPropsGroup();
            Integer lineNo = 0;
            for (int i = 0; i < propsGroup.size(); i++) {
                for (int j = 0; j < propsGroup.get(i).size(); j++) {
                    lineNo++;
                    propsGroup.get(i).get(j).setLineno(lineNo.toString());
                    propsGroup.get(i).get(j).setPlansubcode(request.getPlancode() + i);
                    propsGroup.get(i).get(j).setPlancode(request.getPlancode());
                    propsGroup.get(i).get(j).setRiskcode(request.getRisk().getRiskcode());
                    propsGroup.get(i).get(j).setRiskversion(request.getRisk().getRiskversion());
                    if ("0".equals(propsGroup.get(i).get(j).getPropstype())) {
                        propsGroup.get(i).get(j).setStartvalue(null);
                        propsGroup.get(i).get(j).setEndvalue(null);
                    } else {
                        propsGroup.get(i).get(j).setPropsvalue(null);
                    }
                    propsGroup.get(i).get(j).setValidstatus("1");
                    prpdPlanSubService.insert(propsGroup.get(i).get(j));
                }
            }
			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			//保存方案数据到prpdration
			//JIRA:PRO-171  核心根据序号  （serialno） 来排序并加载条款信息，如果附加险的序号排在主险前可能会引起一些问题，希望平台可以控制下，配置方案时先选主险后选附加险
            List<List<Prpdkindlibrary>> kindsGroup = request.getKindsGroup();
            List<List<Prpdkindlibrary>> sortedKindsGroup = new ArrayList<>();
            for (int i = 0; i < kindsGroup.size(); i++) {
			    List<Prpdkindlibrary> sortedKinds = new ArrayList<>();
                for (int j = 0; j < kindsGroup.get(i).size(); j++) {
                    if (kindsGroup.get(i).get(j).getKindcode().contains("M")) {
                        sortedKinds.add(kindsGroup.get(i).get(j));
                    }
                }
                for (int j = 0; j < kindsGroup.get(i).size(); j++) {
                    if (kindsGroup.get(i).get(j).getKindcode().contains("S")) {
                        sortedKinds.add(kindsGroup.get(i).get(j));
                    }
                }
                sortedKindsGroup.add(sortedKinds);
            }

			StringBuffer planDetails = new StringBuffer();
            long serialNo = 1;
            for (int i = 0; i < sortedKindsGroup.size(); i++) {
                Prpdration ration = new Prpdration();
                for (int j = 0; j < sortedKindsGroup.get(i).size(); j++) {
                    ration.setRationtype(request.getPlantype());
                    ration.setRiskcode(request.getRisk().getRiskcode());
                    ration.setRiskversion(request.getRisk().getRiskversion());
                    ration.setPlancode(request.getPlancode());
                    ration.setPlancname(request.getPlancname());
                    ration.setPlanename(request.getPlanename());
                    ration.setSerialno(serialNo);
                    ration.setKindcode(sortedKindsGroup.get(i).get(j).getKindcode());
                    ration.setKindversion(sortedKindsGroup.get(i).get(j).getKindversion());
                    ration.setKindcname(sortedKindsGroup.get(i).get(j).getKindcname());
                    ration.setKindename(sortedKindsGroup.get(i).get(j).getKindename());
                    ration.setStartdate(sortedKindsGroup.get(i).get(j).getStartdate());
                    ration.setEnddate(sortedKindsGroup.get(i).get(j).getEnddate());
                    ration.setClausecode(sortedKindsGroup.get(i).get(j).getClausecode());
    
                    Prpdkind criteria = new Prpdkind();
                    criteria.setRiskcode(request.getRisk().getRiskcode());
                    criteria.setRiskversion(request.getRisk().getRiskversion());
                    criteria.setKindcode(sortedKindsGroup.get(i).get(j).getKindcode());
                    criteria.setKindversion(sortedKindsGroup.get(i).get(j).getKindversion());
                    List<Prpdkind> ownerRiskKind = prpdKindService.select(criteria);
                    ration.setOwnerriskcode(ownerRiskKind.get(0).getOwnerriskcode());
    
                    ration.setCalculateflag(sortedKindsGroup.get(i).get(j).getCalculateflag());
                    ration.setWaysofcalc(sortedKindsGroup.get(i).get(j).getWaysofcalc());
                    ration.setValidstatus("1");
                    ration.setDelflag(request.getDelflag());
                    for (AmountPremium amountPremium : request.getKinditemsGroup().get(i)) {
                        if (sortedKindsGroup.get(i).get(j).getKindcode().equals(amountPremium.getKindcode())) {
                            ration.setSerialno(serialNo++);
                            ration.setItemcode(amountPremium.getItemcode());
                            ration.setItemcname(amountPremium.getItemcname());
                            ration.setItemename(amountPremium.getItemename());
                            ration.setItemflag(amountPremium.getItemflag());
                            ration.setFreeitem3(amountPremium.getOwnerFlag());
                            ration.setFreeitem4(request.getPlancode() + i);  //plansubcode = plancode + 组号
                            ration.setQuantity(Long.valueOf(amountPremium
                                    .getQuantity()));
                            ration.setCurrency(amountPremium.getCurrency());
                            ration.setAmount(new BigDecimal(amountPremium
                                    .getAmount()));
                            ration.setUnitamount(new BigDecimal(amountPremium
                                    .getUnitamount()));
                            ration.setRate(new BigDecimal(amountPremium.getRate()));
                            ration.setDiscount(new BigDecimal(amountPremium
                                    .getDiscount()));
                            ration.setPremium(new BigDecimal(amountPremium
                                    .getPremium()));
                            ration.setUnitpremium(new BigDecimal(amountPremium
                                    .getUnitpremium()));
                            ration.setCalculateflag(amountPremium.getCalculateflag());
                            String prpdRationFlag = env.getProperty("prpdration."+ request.getRisk().getRiskcode() +".flag");
                            if(StringUtils.isEmpty(prpdRationFlag)) {
                                ration.setFlag("00");
                            } else {
                                ration.setFlag(prpdRationFlag.trim());
                            }
                            prpdrationService.insert(ration);
                            planDetails.append("新增方案明细数据:"
                                    + ObjectUtil.info(ration) + ";");
                        }
                    }
                }
            }

			//////////////////////////////////////////////////////////////////////////////
			//针对复制的方案的情况，如果已配置条件因子，则复制并保存条件因子配置
			if (request.getOriginalPlan() != null) {
				Prpdriskplan planCriteria = new Prpdriskplan();
				planCriteria.setPlancode(request.getOriginalPlan().getPlancode());
				planCriteria.setRiskcode(request.getOriginalPlan().getRiskcode());
				planCriteria.setRiskversion(request.getOriginalPlan().getRiskversion());
				List<Prpdplanprops> planProps = prpdPlanPropsService.select(planCriteria);
				if (!planProps.isEmpty()) {
					////////////////////////////////////////////////////////////////////////////////////////
					/////////////////2724-座位类型特殊处理，临时添加，后期将移除/////////////////////////////////
					////////////////////////////////////////////////////////////////////////////////////////
					if ("2724".equals(request.getOriginalPlan().getRiskcode())) {
						List<Prpdplanprops> multiProps = new ArrayList<Prpdplanprops>();
						for (Prpdplanprops prop : planProps) {
							if ("00001".equals(prop.getPropscode())) { // 00001 - 座位
								multiProps.add(prop);
							}
						}
						if (!CollectionUtil.isEmpty(multiProps)) {
							Prpdplanprops regionProp = null;
							Prpdration record = new Prpdration();
							for (Prpdplanprops prop : multiProps) {
								regionProp = prop;
								record.setFreeitem1(prop.getPropsvalue());
								record.setFreeitem2("");
								if ("1".equals(prop.getPropstype())) { // 座位区间值，优先保存
									record.setFreeitem1(regionProp
											.getStartvalue());
									record.setFreeitem2(regionProp
											.getEndvalue());
									break;
								}
							}
							Prpdration criteria = new Prpdration();
							criteria.setPlancode(request.getPlancode());
							criteria.setRiskcode(request.getRisk().getRiskcode());
							criteria.setRiskversion(request.getRisk().getRiskversion());
							prpdrationService.updateByCriteria(record, criteria);
						}
					}
					////////////////////////////////////////////////////////////////////////////////////////

                    Map<String, Integer> lineNos = new HashMap<>();
					for (Prpdplanprops prop : planProps) {
						prop.setPlancode(request.getPlancode());
                        lineNo = lineNos.get(prop.getPropscode());
						if (lineNo == null) {
							lineNo = 1;
						} else {
							lineNo++;
						}
						lineNos.put(prop.getPropscode(), lineNo);
						prop.setLineno(lineNo.toString());
						if ("0".equals(prop.getPropstype())) {
							prop.setStartvalue(null);
							prop.setEndvalue(null);
						} else {
							prop.setPropsvalue(null);
						}
						prop.setValidstatus("1");
						prpdPlanPropsService.insert(prop);
					}
				}
			}
			//////////////////////////////////////////////////////////////////////////////

			int nextPlanSerialNo = Integer.valueOf(request.getPlancode()
					.substring(8)) + 1;
			prpdSerialNoService.updatePrpdSerialno(
					BUSINESSTYPE.plan.toString(), request.getRisk()
							.getRiskcode().substring(0, 2), request.getRisk()
							.getRiskcode(), nextPlanSerialNo);

			// ********************************************************************************
			// 方案日志
			systemLog
					.save(BUSINESSLOGTYPE.PLAN, OPERTYPE.INSERT,
							request.getPlancode(),
							"新增方案基础数据:" + ObjectUtil.info(riskPlan) + ";"
									+ planDetails);
			// ********************************************************************************
		} catch (Exception e) {
			log.error("系统异常错误！", e);
			throw e;
		}

		return result;
	}

	@Override
	public Response findKindItems(String plancode) {
		Response result = new Response();
		try {
			List<Prpdration> list = prpdrationService.findByPlanCode(plancode,
					true);

			Set<Prpdkindlibrary> kinds = new HashSet<>();
			List<ItemKind> items = new ArrayList<>();
			List<AmountPremium> kinditems = new ArrayList<>();
			Prpdkindlibrary kind;
			ItemKind item;
			AmountPremium amountPremium;
			String kindDelFlag = null;

			if (list.isEmpty()) {
				List<Prpdration> rs = prpdrationService.findByPlanCode(
						plancode, false);
				kindDelFlag = rs.get(0).getDelflag();
			}

			for (Prpdration prpdration : list) {

				if (kindDelFlag == null) {
					kindDelFlag = prpdration.getDelflag();
				}

				amountPremium = new AmountPremium();
				amountPremium.setKindcode(prpdration.getKindcode());
				amountPremium.setKindversion(prpdration.getKindversion());
				amountPremium.setKindcname(prpdration.getKindcname());
				amountPremium.setKindename(prpdration.getKindename());
				amountPremium.setItemcode(prpdration.getItemcode());
				amountPremium.setItemcname(prpdration.getItemcname());
				amountPremium.setItemename(prpdration.getItemename());
				amountPremium.setItemflag(prpdration.getItemflag());
				amountPremium.setOwnerFlag(prpdration.getFreeitem3());
				amountPremium.setQuantity(prpdration.getQuantity().toString());
				amountPremium.setCurrency(prpdration.getCurrency());
				amountPremium.setAmount(prpdration.getAmount().toString());
				amountPremium.setUnitamount(prpdration.getUnitamount()
						.toString());
				amountPremium.setRate(prpdration.getRate().toString());
				amountPremium.setDiscount(prpdration.getDiscount().toString());
				amountPremium.setPremium(prpdration.getPremium().toString());
				amountPremium.setUnitpremium(prpdration.getUnitpremium()
						.toString());
				amountPremium.setCalculateflag(prpdration.getCalculateflag());
				kinditems.add(amountPremium);

				kind = new Prpdkindlibrary();
				kind.setKindcode(prpdration.getKindcode());
				kind.setKindversion(prpdration.getKindversion());
				kind.setKindcname(prpdration.getKindcname());
				kind.setKindename(prpdration.getKindename());
				kind.setStartdate(prpdration.getStartdate());
				kind.setEnddate(prpdration.getEnddate());
				kind.setClausecode(prpdration.getClausecode());
				kind.setCalculateflag(prpdration.getCalculateflag());
				kind.setOwnerriskcode(prpdration.getOwnerriskcode());
				kind.setWaysofcalc(prpdration.getWaysofcalc());

				///////////////////////////////////////////////////////////////////////
				//kind根据kindcode、kindversion去重
				boolean isExisted = false;
				for(Prpdkindlibrary k : kinds) {
					if(prpdration.getKindcode().equals(k.getKindcode()) && prpdration.getKindversion().equals(k.getKindversion())) {
						isExisted = true;
						break;
					}
				}
				if(!isExisted) {
					kinds.add(kind);
				}
				///////////////////////////////////////////////////////////////////////
				
				
				if (prpdration.getItemcode() != null
						&& !"".equals(prpdration.getItemcode())) {
					item = new ItemKind();
					item.setItemcode(prpdration.getItemcode());
					item.setItemcname(prpdration.getItemcname());
					item.setItemename(prpdration.getItemename());
					item.setItemflag(prpdration.getItemflag());
					item.setKindcode(prpdration.getKindcode());
					item.setKindversion(prpdration.getKindversion());
					item.setKey(prpdration.getItemcode()
							+ prpdration.getKindcode());
					items.add(item);
				}
			}

			Map<String, Object> data = new HashMap<>();
			data.put("delflag", kindDelFlag);
			data.put("kinds", kinds);
			data.put("items", items);
			data.put("kinditems", kinditems);
			result.setResult(data);
			result.setSuccess();
		} catch (Exception e) {
			log.error("系统异常错误！", e);
			result.setAppFail();
			result.setResult(e.getMessage());
		}
		return result;
	}

	@Override
	public Response findKindItems2(String plancode) {
		Response result = new Response();
		try {

            List<List<Prpdplansub>> propsGroup = new ArrayList<>();
            List<Set<Prpdkindlibrary>> kindsGroup = new ArrayList<>();
            List<List<ItemKind>> itemsGroup = new ArrayList<>();
            List<List<AmountPremium>> kinditemsGroup = new ArrayList<>();
			String kindDelFlag = null;

            ////////////////////////////////////////////////////////////////////
            //组装费率因子数据
            Prpdriskplan criteria = new Prpdriskplan();
            criteria.setPlancode(plancode);
            List<Prpdplansub> propsList = prpdPlanSubService.select(criteria);
            Map<String, List<Prpdplansub>> tmpPropsMap = new HashMap<>();
            Prpdplansub prop;
            for (Prpdplansub prpdplansub : propsList) {
                List<Prpdplansub> currentProps = tmpPropsMap.get(prpdplansub.getPlansubcode());
                if (currentProps == null) {
                    currentProps = new ArrayList<>();
                    tmpPropsMap.put(prpdplansub.getPlansubcode(), currentProps);
                }
                prop = new Prpdplansub();
                prop.setPropscode(prpdplansub.getPropscode());
                prop.setPropstype(prpdplansub.getPropstype());
                prop.setPropsvalue(prpdplansub.getPropsvalue());
                prop.setStartvalue(prpdplansub.getStartvalue());
                prop.setEndvalue(prpdplansub.getEndvalue());
				prop.setLineno(prpdplansub.getLineno());
                currentProps.add(prop);
            }
            for(Map.Entry<String, List<Prpdplansub>> rs : tmpPropsMap.entrySet()) {
                propsGroup.add(rs.getValue());
            }
			//因子组按保存时顺序重新排序
			List<List<Prpdplansub>> tmpPropsGroup = propsGroup.stream().sorted(Comparator.comparing(e -> {return e.get(0).getLineno();})).collect(Collectors.toList());
			propsGroup = tmpPropsGroup;
            ////////////////////////////////////////////////////////////////////
            //组装条款/责任/保额保费数据
            List<Prpdration> rationList = prpdrationService.findByPlanCode(plancode, true);
			if (rationList.isEmpty()) {
				List<Prpdration> rs = prpdrationService.findByPlanCode(
						plancode, false);
				kindDelFlag = rs.get(0).getDelflag();
			}
            Map<String, Set<Prpdkindlibrary>> tmpKindsMap = new HashMap<>();
            Map<String, List<ItemKind>> tmpItemsMap = new HashMap<>();
            Map<String, List<AmountPremium>> tmpKinditemsMap = new HashMap<>();
			Prpdkindlibrary kind;
			ItemKind item;
			AmountPremium amountPremium;
			for (Prpdration prpdration : rationList) {

				if (kindDelFlag == null) {
					kindDelFlag = prpdration.getDelflag();
				}

                Set<Prpdkindlibrary> currentKinds = tmpKindsMap.get(prpdration.getFreeitem4());
                List<ItemKind> currentItems = tmpItemsMap.get(prpdration.getFreeitem4());
                List<AmountPremium> currentKinditems = tmpKinditemsMap.get(prpdration.getFreeitem4());
                if (currentKinds == null) {
                    currentKinds = new HashSet<>();
                    tmpKindsMap.put(prpdration.getFreeitem4(), currentKinds);
                }
                if (currentItems == null) {
                    currentItems = new ArrayList<>();
                    tmpItemsMap.put(prpdration.getFreeitem4(), currentItems);
                }
                if (currentKinditems == null) {
                    currentKinditems = new ArrayList<>();
                    tmpKinditemsMap.put(prpdration.getFreeitem4(), currentKinditems);
                }

				amountPremium = new AmountPremium();
				amountPremium.setSerialno(prpdration.getSerialno());
				amountPremium.setKindcode(prpdration.getKindcode());
				amountPremium.setKindversion(prpdration.getKindversion());
				amountPremium.setKindcname(prpdration.getKindcname());
				amountPremium.setKindename(prpdration.getKindename());
				amountPremium.setItemcode(prpdration.getItemcode());
				amountPremium.setItemcname(prpdration.getItemcname());
				amountPremium.setItemename(prpdration.getItemename());
				amountPremium.setItemflag(prpdration.getItemflag());
				amountPremium.setOwnerFlag(prpdration.getFreeitem3());
				amountPremium.setQuantity(prpdration.getQuantity().toString());
				amountPremium.setCurrency(prpdration.getCurrency());
				amountPremium.setAmount(prpdration.getAmount().toString());
				amountPremium.setUnitamount(prpdration.getUnitamount()
						.toString());
				amountPremium.setRate(prpdration.getRate().toString());
				amountPremium.setDiscount(prpdration.getDiscount().toString());
				amountPremium.setPremium(prpdration.getPremium().toString());
				amountPremium.setUnitpremium(prpdration.getUnitpremium()
						.toString());
				amountPremium.setCalculateflag(prpdration.getCalculateflag());
                currentKinditems.add(amountPremium);

				kind = new Prpdkindlibrary();
				kind.setKindcode(prpdration.getKindcode());
				kind.setKindversion(prpdration.getKindversion());
				kind.setKindcname(prpdration.getKindcname());
				kind.setKindename(prpdration.getKindename());
				kind.setStartdate(prpdration.getStartdate());
				kind.setEnddate(prpdration.getEnddate());
				kind.setClausecode(prpdration.getClausecode());
				kind.setCalculateflag(prpdration.getCalculateflag());
				kind.setOwnerriskcode(prpdration.getOwnerriskcode());
				kind.setWaysofcalc(prpdration.getWaysofcalc());

				///////////////////////////////////////////////////////////////////////
				//kind根据kindcode、kindversion去重
				boolean isExisted = false;
				for(Prpdkindlibrary k : currentKinds) {
					if(prpdration.getKindcode().equals(k.getKindcode()) && prpdration.getKindversion().equals(k.getKindversion())) {
						isExisted = true;
						break;
					}
				}
				if(!isExisted) {
                    currentKinds.add(kind);
				}
				///////////////////////////////////////////////////////////////////////


				if (prpdration.getItemcode() != null
						&& !"".equals(prpdration.getItemcode())) {
					item = new ItemKind();
					item.setItemcode(prpdration.getItemcode());
					item.setItemcname(prpdration.getItemcname());
					item.setItemename(prpdration.getItemename());
					item.setItemflag(prpdration.getItemflag());
					item.setKindcode(prpdration.getKindcode());
					item.setKindversion(prpdration.getKindversion());
					item.setKey(prpdration.getItemcode()
							+ prpdration.getKindcode());
                    currentItems.add(item);
				}
			}


			//条款和责任组按保存时顺序重新排序
			Map<Integer, Set<Prpdkindlibrary>> newKindsMap = new HashMap<>();
			Map<Integer, List<ItemKind>> newItemsMap = new HashMap<>();
			Map<Integer, Set<Prpdkindlibrary>> sortedNewKindsMap = new HashMap<>();
			Map<Integer, List<ItemKind>> sortedNewItemsMap = new HashMap<>();
			for(Map.Entry<String, Set<Prpdkindlibrary>> rs : tmpKindsMap.entrySet()) {
				newKindsMap.put(Integer.valueOf(rs.getKey().substring(13)), rs.getValue());  //方案代码字符串长度13
			}
			for(Map.Entry<String, List<ItemKind>> rs : tmpItemsMap.entrySet()) {
				newItemsMap.put(Integer.valueOf(rs.getKey().substring(13)), rs.getValue());
			}
			newKindsMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEachOrdered(e -> sortedNewKindsMap.put(e.getKey(), e.getValue()));
			newItemsMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEachOrdered(e -> sortedNewItemsMap.put(e.getKey(), e.getValue()));
			//条款和责任组按保存时顺序重新排序-End


            for(Map.Entry<Integer, Set<Prpdkindlibrary>> rs : sortedNewKindsMap.entrySet()) {
                kindsGroup.add(rs.getValue());
            }
            for(Map.Entry<Integer, List<ItemKind>> rs : sortedNewItemsMap.entrySet()) {
                itemsGroup.add(rs.getValue());
            }
            for(Map.Entry<String, List<AmountPremium>> rs : tmpKinditemsMap.entrySet()) {
                kinditemsGroup.add(rs.getValue());
            }

			//保额保费组按保存时顺序重新排序
			List<List<AmountPremium>> tmpKinditemsGroup = kinditemsGroup.stream().sorted(Comparator.comparing(e -> {return e.get(0).getSerialno();})).collect(Collectors.toList());
			kinditemsGroup = tmpKinditemsGroup;

			Map<String, Object> data = new HashMap<>();
			data.put("delflag", kindDelFlag);
			data.put("propsGroup", propsGroup);
			data.put("kindsGroup", kindsGroup);
			data.put("itemsGroup", itemsGroup);
			data.put("kinditemsGroup", kinditemsGroup);
			result.setResult(data);
			result.setSuccess();
		} catch (Exception e) {
			log.error("系统异常错误！", e);
			result.setAppFail();
			result.setResult(e.getMessage());
		}
		return result;
	}

    @Override
    public Response queryPlansub(String plancode) {
        Response result = new Response();
        try {
            Prpdriskplan criteria = new Prpdriskplan();
            criteria.setPlancode(plancode);
            List<Prpdplansub> rs = prpdPlanSubService.select(criteria);

            if (rs.isEmpty()) {
                result.setResult(false);
            } else {
                result.setResult(true);
            }
            result.setSuccess();
        } catch (Exception e) {
            log.error("系统异常错误！", e);
            result.setAppFail();
            result.setResult(e.getMessage());
        }
        return result;
    }

    @Override
	public Response updatePlanInfo(PlanAddRequest request) throws Exception {

		Response result = new Response();

		try {
			// 更新方案数据到prpdriskplan
			PrpdriskplanWithBLOBs riskPlan = new PrpdriskplanWithBLOBs();
			riskPlan.setPlancode(request.getPlancode());
			riskPlan.setRiskcode(request.getRisk().getRiskcode());
			riskPlan.setRiskversion(request.getRisk().getRiskversion());
			riskPlan.setPlancname(request.getPlancname());
			riskPlan.setPlanename(request.getPlanename());
			riskPlan.setSerialno(1L);
			riskPlan.setValidstatus(request.getValidstatus());
			riskPlan.setFlag(request.getPlantype());
			riskPlan.setPlantype(request.getPlantype());
            if(!StringUtils.isEmpty(request.getApplycomcode()) && request.getApplycomcode().contains("ALL")) {
                riskPlan.setApplycomcode("ALL");
            } else {
                riskPlan.setApplycomcode(request.getApplycomcode());
            }
			riskPlan.setApplychannel(request.getApplychannel());
			riskPlan.setAutoundwrt(request.getAutoundwrt());
			riskPlan.setAutodoc(request.getAutodoc());
			riskPlan.setPeriodtype(request.getPeriodtype());
			riskPlan.setPeriod(Integer.valueOf("".equals(request.getPeriod()) ? "0"
					: request.getPeriod()));
			riskPlan.setOccupationcode(request.getOccupationcode());
			riskPlan.setTraveldestination(request.getTraveldestination());
			riskPlan.setUpdatedate(new Date());
			prpdRiskPlanService.update(riskPlan);

			// 更新方案数据到prpdration
			StringBuffer planDetails = new StringBuffer();
			List<Prpdration> requestRations = new ArrayList<Prpdration>();
			Prpdration ration = null;
			for (Prpdkindlibrary kind : request.getKinds()) {
				for (AmountPremium amountPremium : request.getKinditems()) {
					if (kind.getKindcode().equals(amountPremium.getKindcode())) {
						ration = new Prpdration();
						ration.setRationtype(request.getPlantype());
						ration.setRiskcode(request.getRisk().getRiskcode());
						ration.setRiskversion(request.getRisk().getRiskversion());
						ration.setPlancode(request.getPlancode());
						ration.setPlancname(request.getPlancname());
						ration.setPlanename(request.getPlanename());
						ration.setKindcode(kind.getKindcode());
						ration.setKindversion(kind.getKindversion());
						ration.setKindcname(kind.getKindcname());
						ration.setKindename(kind.getKindename());
						ration.setStartdate(kind.getStartdate());
						ration.setEnddate(kind.getEnddate());
						ration.setClausecode(kind.getClausecode());
						
						Prpdkind criteria = new Prpdkind();
						criteria.setRiskcode(request.getRisk().getRiskcode());
						criteria.setRiskversion(request.getRisk().getRiskversion());
						criteria.setKindcode(kind.getKindcode());
						criteria.setKindversion(kind.getKindversion());
						List<Prpdkind> ownerRiskKind = prpdKindService.select(criteria);
						ration.setOwnerriskcode(ownerRiskKind.get(0).getOwnerriskcode());
						
						ration.setCalculateflag(kind.getCalculateflag());
						ration.setFreeitem3(amountPremium.getOwnerFlag());
						ration.setWaysofcalc(kind.getWaysofcalc());
						ration.setDelflag(request.getDelflag());
						ration.setItemcode(amountPremium.getItemcode());
						ration.setItemcname(amountPremium.getItemcname());
						ration.setItemename(amountPremium.getItemename());
						ration.setItemflag(amountPremium.getItemflag());
						ration.setQuantity(Long.valueOf(amountPremium
								.getQuantity()));
						ration.setCurrency(amountPremium.getCurrency());
						ration.setAmount(new BigDecimal(amountPremium
								.getAmount()));
						ration.setUnitamount(new BigDecimal(amountPremium
								.getUnitamount()));
						ration.setRate(new BigDecimal(amountPremium.getRate()));
						ration.setDiscount(new BigDecimal(amountPremium
								.getDiscount()));
						ration.setPremium(new BigDecimal(amountPremium
								.getPremium()));
						ration.setUnitpremium(new BigDecimal(amountPremium
								.getUnitpremium()));
						ration.setValidstatus("1");
						ration.setCalculateflag(amountPremium.getCalculateflag());
						requestRations.add(ration);
						planDetails.append("修改后-方案明细数据:"
								+ ObjectUtil.info(ration) + ";");
					}
				}
			}

			// ********************************************************************************************
			// 如果新增加了条款
			List<Prpdration> dbRations = prpdrationService.findByPlanCode(
					request.getPlancode(), null);
			for (Prpdration requestRation : requestRations) {
				boolean isExisted = false;
				for (Prpdration dbRation : dbRations) {
					if (requestRation.getPlancode().equals(
							dbRation.getPlancode())
							&& requestRation.getRiskcode().equals(
									dbRation.getRiskcode())
							&& requestRation.getRiskversion().equals(
									dbRation.getRiskversion())
							&& requestRation.getKindcode().equals(
									dbRation.getKindcode())
							&& requestRation.getKindversion().equals(
									dbRation.getKindversion())) {

						String requestItemcode = requestRation.getItemcode();
						if ((requestItemcode == null && dbRation.getItemcode() == null)
								|| ((requestItemcode == null ? ""
										: requestItemcode).equals(dbRation
										.getItemcode()))) {

							prpdrationService.update(requestRation);
							isExisted = true;

						}

					}
				}
				if (!isExisted) {
					int maxSerialNum = prpdrationService
							.getMaxSerialNum(requestRation);
					requestRation.setSerialno(Long.valueOf(maxSerialNum + 1));
					String prpdRationFlag = env.getProperty("prpdration."+ request.getRisk().getRiskcode() +".flag");
					if(StringUtils.isEmpty(prpdRationFlag)) {
						requestRation.setFlag("00");
					} else {
						requestRation.setFlag(prpdRationFlag.trim());
					}
					prpdrationService.insert(requestRation);
				}
			}

			// ********************************************************************************************
			// 如果删除了条款
			dbRations = prpdrationService.findByPlanCode(request.getPlancode(),
					null);
			for (Prpdration dbRation : dbRations) {
				boolean isDeleted = true;

				for (Prpdration requestRation : requestRations) {
					if (requestRation.getPlancode().equals(
							dbRation.getPlancode())
							&& requestRation.getRiskcode().equals(
									dbRation.getRiskcode())
							&& requestRation.getRiskversion().equals(
									dbRation.getRiskversion())
							&& requestRation.getKindcode().equals(
									dbRation.getKindcode())
							&& requestRation.getKindversion().equals(
									dbRation.getKindversion())) {

						String requestItemcode = requestRation.getItemcode();
						if ((requestItemcode == null && dbRation.getItemcode() == null)
								|| ((requestItemcode == null ? ""
										: requestItemcode).equals(dbRation
										.getItemcode()))) {

							isDeleted = false;

						}

					}
				}
				if (isDeleted) {
					Prpdration record = new Prpdration();
					record.setPlancode(dbRation.getPlancode());
					record.setRiskcode(dbRation.getRiskcode());
					record.setRiskversion(dbRation.getRiskversion());
					record.setKindcode(dbRation.getKindcode());
					record.setKindversion(dbRation.getKindversion());
					record.setItemcode(dbRation.getItemcode());
					record.setValidstatus("0");
					prpdrationService.update(record);
				}
			}

			// ********************************************************************************
			// 方案日志
			systemLog.save(BUSINESSLOGTYPE.PLAN, OPERTYPE.UPDATE,
					request.getPlancode(),
					"修改后-方案基础数据:" + ObjectUtil.info(riskPlan) + ";"
							+ planDetails);
			// ********************************************************************************
		} catch (Exception e) {
			log.error("系统异常错误！", e);
			throw e;
		}

		return result;
	}

    @Override
	public Response updatePlanInfo2(PlanAddRequest2 request) throws Exception {

		Response result = new Response();

		try {
			// 更新方案数据到prpdriskplan
			PrpdriskplanWithBLOBs riskPlan = new PrpdriskplanWithBLOBs();
			riskPlan.setPlancode(request.getPlancode());
			riskPlan.setRiskcode(request.getRisk().getRiskcode());
			riskPlan.setRiskversion(request.getRisk().getRiskversion());
			riskPlan.setPlancname(request.getPlancname());
			riskPlan.setPlanename(request.getPlanename());
			riskPlan.setSerialno(1L);
			riskPlan.setValidstatus(request.getValidstatus());
			riskPlan.setFlag(request.getPlantype());
			riskPlan.setPlantype(request.getPlantype());
            if(!StringUtils.isEmpty(request.getApplycomcode()) && request.getApplycomcode().contains("ALL")) {
                riskPlan.setApplycomcode("ALL");
            } else {
                riskPlan.setApplycomcode(request.getApplycomcode());
            }
			riskPlan.setApplychannel(request.getApplychannel());
			riskPlan.setAutoundwrt(request.getAutoundwrt());
			riskPlan.setAutodoc(request.getAutodoc());
			riskPlan.setPeriodtype(request.getPeriodtype());
			riskPlan.setPeriod(Integer.valueOf("".equals(request.getPeriod()) ? "0"
					: request.getPeriod()));
			riskPlan.setOccupationcode(request.getOccupationcode());
			riskPlan.setTraveldestination(request.getTraveldestination());
			riskPlan.setUpdatedate(new Date());
			prpdRiskPlanService.update(riskPlan);

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //保存因子组数据到prpdplansub
            Prpdriskplan where1 = new Prpdriskplan();
            where1.setPlancode(request.getPlancode());
            where1.setRiskcode(request.getRisk().getRiskcode());
            where1.setRiskversion(request.getRisk().getRiskversion());
            prpdPlanSubService.deleteByPlan(where1);
            List<List<Prpdplansub>> propsGroup = request.getPropsGroup();
            Integer lineNo = 0;
            for (int i = 0; i < propsGroup.size(); i++) {
                for (int j = 0; j < propsGroup.get(i).size(); j++) {
                    lineNo++;
                    propsGroup.get(i).get(j).setLineno(lineNo.toString());
                    propsGroup.get(i).get(j).setPlansubcode(request.getPlancode() + i);
                    propsGroup.get(i).get(j).setPlancode(request.getPlancode());
                    propsGroup.get(i).get(j).setRiskcode(request.getRisk().getRiskcode());
                    propsGroup.get(i).get(j).setRiskversion(request.getRisk().getRiskversion());
                    if ("0".equals(propsGroup.get(i).get(j).getPropstype())) {
                        propsGroup.get(i).get(j).setStartvalue(null);
                        propsGroup.get(i).get(j).setEndvalue(null);
                    } else {
                        propsGroup.get(i).get(j).setPropsvalue(null);
                    }
                    propsGroup.get(i).get(j).setValidstatus("1");
                    prpdPlanSubService.insert(propsGroup.get(i).get(j));
                }
            }
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //保存方案数据到prpdration
            //JIRA:PRO-171  核心根据序号  （serialno） 来排序并加载条款信息，如果附加险的序号排在主险前可能会引起一些问题，希望平台可以控制下，配置方案时先选主险后选附加险
            List<List<Prpdkindlibrary>> kindsGroup = request.getKindsGroup();
            List<List<Prpdkindlibrary>> sortedKindsGroup = new ArrayList<>();
            for (int i = 0; i < kindsGroup.size(); i++) {
                List<Prpdkindlibrary> sortedKinds = new ArrayList<>();
                for (int j = 0; j < kindsGroup.get(i).size(); j++) {
                    if (kindsGroup.get(i).get(j).getKindcode().contains("M")) {
                        sortedKinds.add(kindsGroup.get(i).get(j));
                    }
                }
                for (int j = 0; j < kindsGroup.get(i).size(); j++) {
                    if (kindsGroup.get(i).get(j).getKindcode().contains("S")) {
                        sortedKinds.add(kindsGroup.get(i).get(j));
                    }
                }
                sortedKindsGroup.add(sortedKinds);
            }

            Prpdration where2 = new Prpdration();
            where2.setPlancode(request.getPlancode());
            where2.setRiskcode(request.getRisk().getRiskcode());
            where2.setRiskversion(request.getRisk().getRiskversion());
            prpdrationService.deleteByPlan(where2);

            StringBuffer planDetails = new StringBuffer();
            long serialNo = 1;
            for (int i = 0; i < sortedKindsGroup.size(); i++) {
                Prpdration ration = new Prpdration();
                for (int j = 0; j < sortedKindsGroup.get(i).size(); j++) {
                    ration.setRationtype(request.getPlantype());
                    ration.setRiskcode(request.getRisk().getRiskcode());
                    ration.setRiskversion(request.getRisk().getRiskversion());
                    ration.setPlancode(request.getPlancode());
                    ration.setPlancname(request.getPlancname());
                    ration.setPlanename(request.getPlanename());
                    ration.setSerialno(serialNo);
                    ration.setKindcode(sortedKindsGroup.get(i).get(j).getKindcode());
                    ration.setKindversion(sortedKindsGroup.get(i).get(j).getKindversion());
                    ration.setKindcname(sortedKindsGroup.get(i).get(j).getKindcname());
                    ration.setKindename(sortedKindsGroup.get(i).get(j).getKindename());
                    ration.setStartdate(sortedKindsGroup.get(i).get(j).getStartdate());
                    ration.setEnddate(sortedKindsGroup.get(i).get(j).getEnddate());
                    ration.setClausecode(sortedKindsGroup.get(i).get(j).getClausecode());

                    Prpdkind criteria = new Prpdkind();
                    criteria.setRiskcode(request.getRisk().getRiskcode());
                    criteria.setRiskversion(request.getRisk().getRiskversion());
                    criteria.setKindcode(sortedKindsGroup.get(i).get(j).getKindcode());
                    criteria.setKindversion(sortedKindsGroup.get(i).get(j).getKindversion());
                    List<Prpdkind> ownerRiskKind = prpdKindService.select(criteria);
                    ration.setOwnerriskcode(ownerRiskKind.get(0).getOwnerriskcode());

                    ration.setCalculateflag(sortedKindsGroup.get(i).get(j).getCalculateflag());
                    ration.setWaysofcalc(sortedKindsGroup.get(i).get(j).getWaysofcalc());
                    ration.setValidstatus("1");
                    ration.setDelflag(request.getDelflag());
                    for (AmountPremium amountPremium : request.getKinditemsGroup().get(i)) {
                        if (sortedKindsGroup.get(i).get(j).getKindcode().equals(amountPremium.getKindcode())) {
                            ration.setSerialno(serialNo++);
                            ration.setItemcode(amountPremium.getItemcode());
                            ration.setItemcname(amountPremium.getItemcname());
                            ration.setItemename(amountPremium.getItemename());
                            ration.setItemflag(amountPremium.getItemflag());
                            ration.setFreeitem3(amountPremium.getOwnerFlag());
                            ration.setFreeitem4(request.getPlancode() + i);  //plansubcode = plancode + 组号
                            ration.setQuantity(Long.valueOf(amountPremium
                                    .getQuantity()));
                            ration.setCurrency(amountPremium.getCurrency());
                            ration.setAmount(new BigDecimal(amountPremium
                                    .getAmount()));
                            ration.setUnitamount(new BigDecimal(amountPremium
                                    .getUnitamount()));
                            ration.setRate(new BigDecimal(amountPremium.getRate()));
                            ration.setDiscount(new BigDecimal(amountPremium
                                    .getDiscount()));
                            ration.setPremium(new BigDecimal(amountPremium
                                    .getPremium()));
                            ration.setUnitpremium(new BigDecimal(amountPremium
                                    .getUnitpremium()));
                            ration.setCalculateflag(amountPremium.getCalculateflag());
                            String prpdRationFlag = env.getProperty("prpdration."+ request.getRisk().getRiskcode() +".flag");
                            if(StringUtils.isEmpty(prpdRationFlag)) {
                                ration.setFlag("00");
                            } else {
                                ration.setFlag(prpdRationFlag.trim());
                            }
                            prpdrationService.insert(ration);
                            planDetails.append("修改后-方案明细数据:"
                                    + ObjectUtil.info(ration) + ";");
                        }
                    }
                }
            }

			// ********************************************************************************
			// 方案日志
			systemLog.save(BUSINESSLOGTYPE.PLAN, OPERTYPE.UPDATE,
					request.getPlancode(),
					"修改后-方案基础数据:" + ObjectUtil.info(riskPlan) + ";"
							+ planDetails);
			// ********************************************************************************
		} catch (Exception e) {
			log.error("系统异常错误！", e);
			throw e;
		}

		return result;
	}

}
